#ifndef LFAULT_H_
#define LFAULT_H_

/*
	Copyright (C) 2011 Salil Bhagurkar

	This file is part of illusion

	illusion is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	illusion is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with illusion.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <kernel/vfs.h>
#include <kernel/process.h>

/*
 * Fault flags
 */

//Caused due to an absent page
#define LF_ABSENT (1 << 0)

//Caused due to protection violation
#define LF_VIOLATION (1 << 1)

//Caused due to read on the page
#define LF_READ (1 << 2)

//Caused due to write on the page
#define LF_WRITE (1 << 3)

//Caused from kernel mode or user mode
#define LF_KERNEL (1 << 4)
#define LF_USER (1 << 5)

//Some kind of unexpected big bad error
#define LF_UNEXPECTED (1 << 6)

//Caused due to code or data
#define LF_CODE (1 << 7)
#define LF_DATA (1 << 8)

struct legal_fault {
	char has_source;
	//A simple name of the legal_fault object.
	//This is not to be altered or provided with a stack
	//pointer. This is just to identify the kind of legal
	//fault region registered
	const char *name;
	//The flags that identify what kind of legal fault is expected
	u32 flags;
	//The mask of the flags that need to be checked
	u32 check_mask;
	//The virtual address that marks the start of this region
	void *virt;
	//The number of pages in the region
	uint_t page_count;
	//The source vfs node that contains the data
	struct vfs_node *vfs_node;
	//The offset into the vfs node data from t
	uint_t offset;
	//Linked list pointers
	struct legal_fault *next, *prev;
};


void register_legal_fault(struct process *process, const char *name,
		u32 flags, u32 check_mask, void *virt,
		uint_t page_count, struct vfs_node *vfs_node,
		uint_t offset);
void register_legal_fault_no_source(struct process *process, const char *name,
		u32 flags, u32 check_mask, void *virt,
		uint_t page_count);
void unregister_legal_faults(struct process *process);
int handle_page_fault(void *fault_address, u32 fault_flags);


#endif /* LFAULT_H_ */
